home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 May: Tool Chest / Dev.CD May 98 TC.toast / Tool Chest / Development Kits / HyperCard Related / APDA HyperCard Toolkits / CD Audio Toolkit 1.0 / Source / CDReadTOC.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-02-07  |  6.4 KB  |  262 lines  |  [TEXT/MPS ]

  1. /*
  2.     CDReadTOC - An XFCN to read the table of contents of a CD
  3.     ©Apple Computer, Inc. 1988
  4.     All Rights Reserved.
  5.     
  6.     88/10/08    BL°B    First Version
  7.  
  8.     To compile and link this file using Macintosh Programmer's Workshop,
  9.  
  10.     C -q2 CDReadTOC.c
  11.     link -sn Main=CDReadTOC -sn STDIO=CDReadTOC ∂
  12.          -sn INTENV=CDReadTOC -rt XFCN=42 ∂
  13.          -m CDReadTOC CDReadTOC.c.o "{CLibraries}"CRuntime.o ∂
  14.          "{CLibraries}"StdCLib.o ∂
  15.          -o HyperCommands
  16.          
  17.     This link directive puts the XCMD in the file "HyperCommands".
  18.     Substitute the name of the stack you want it in.  To move XCMDs
  19.     between stacks, use ResEdit.  They can be in an individual stack,
  20.     the Home stack, the HyperCard application, or the System File.
  21.     
  22. */
  23.  
  24. #include <cd.h>
  25.  
  26. typedef struct {
  27.     long    minute;
  28.     long    second;
  29.     long    block;
  30. } TrackInfo;
  31.  
  32. /* prototype definitions for functions */
  33. OSErr    GetNumberTracks(short, short *);
  34. OSErr    ReadTOC(short, short, TrackInfo *);
  35. void    CFormatString(char *, long *, long);
  36.  
  37. /* **** WARNING:  DO NOT USE GLOBAL VARIABLES! **** */
  38.  
  39.  
  40. /************************************************************************
  41.  *
  42.  *  Function:        CDReadTOC
  43.  *
  44.  *  Purpose:        Read table of contents
  45.  *
  46.  *  Returns:        result of driver call to ReadTOC
  47.  *                    normally 0, but could have parameter error or
  48.  *                    other error if non-existent block is specified
  49.  *
  50.  *  Side Effects:
  51.  *
  52.  *  Description:    We need no parameter:
  53.  *                    Get the ioRefNum that we got from previously calling
  54.  *                    CDOpen() by accessing the famous global.
  55.  *
  56.  ************************************************************************/
  57. pascal void
  58. CDReadTOC(paramPtr)
  59. XCmdBlockPtr    paramPtr;
  60. {
  61.     Str31    returnString;
  62.     OSErr    result;
  63.     short    ioRefNum;
  64.     Handle    refHandle;
  65.     
  66.     short    numberTracks;
  67.     TrackInfo    **trackHandle;
  68.     
  69.     Handle    formatString;
  70.         
  71.     /* Must be no parameter */
  72.     if ((paramPtr->paramCount) != 0)
  73.     {
  74.         /* Report error in parameters by returning -1 */
  75.         NumToStr(paramPtr, (long) -1, &returnString);
  76.         paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
  77.         return;
  78.     }
  79.     
  80.     /* Get the global ioRefNum and convert it. */
  81.     refHandle = GetGlobal(paramPtr, GLOBALNAME);
  82.     ioRefNum = atoi(*(refHandle));
  83.     DisposHandle(refHandle);
  84.     ioRefNum &= 0xFFFF;            /* remove vRefNum; not needed. */
  85.     
  86.     result = GetNumberTracks(ioRefNum, &numberTracks);
  87.     
  88.     trackHandle = (TrackInfo **) 0;        /* so final DisposHandle will work */
  89.     
  90.     if (result == noErr)
  91.     {
  92.         trackHandle = NewHandle(numberTracks * sizeof(TrackInfo));
  93.         if (trackHandle == (TrackInfo **) 0)
  94.             result = MemError();
  95.         HLock(trackHandle);
  96.     }
  97.     
  98.     if (result == noErr)
  99.         result = ReadTOC(ioRefNum, numberTracks, *trackHandle);
  100.  
  101.     formatString = NewHandle(1000);    /* we can 99 tracks * 9 bytes per track */
  102.     if (formatString == nil)
  103.         result = MemError();
  104.  
  105.     if (result == noErr)
  106.     {
  107.         HLock(formatString);
  108.         CFormatString((char *)*formatString, *trackHandle, numberTracks * 3);
  109.         HUnlock(formatString);
  110.         paramPtr->returnValue = formatString;    /* let HyperCard do the dispose */
  111.     }
  112.     else
  113.     {
  114.         /* We had an error.  Convert result to string & return it */
  115.         NumToStr(paramPtr, (long) result, &returnString);
  116.         paramPtr->returnValue = PasToZero(paramPtr, (StringPtr) &returnString);
  117.         if (formatString != nil)
  118.             DisposHandle(formatString);    /* only dispose of this if we aren't */
  119.                                         /* returning it to Hypercard */
  120.     }
  121.  
  122.     if (trackHandle != (TrackInfo **) 0)
  123.     {
  124.         HUnlock(trackHandle);
  125.         DisposHandle(trackHandle);
  126.     }
  127. }
  128.  
  129.  
  130.  
  131. /************************************************************************
  132.  *
  133.  *  Function:        GetNumberTracks
  134.  *
  135.  *  Purpose:        report how many tracks are on this CD
  136.  *
  137.  *  Returns:        OSErr.  Probably either
  138.  *                        noErr        everything's hunky-dory!
  139.  *                        paramErr    you messed up the call somehow.
  140.  *
  141.  *  Side Effects:    none
  142.  *
  143.  *  Description:    Simply call the driver.
  144.  *
  145.  ************************************************************************/
  146. OSErr
  147. GetNumberTracks(refNum, numberTracks)
  148. short    refNum;
  149. short    *numberTracks;
  150. {
  151.     CDParam    myPB;
  152.     OSErr    result;
  153.     
  154.     myPB.ioCompletion = 0;
  155.     myPB.ioNamePtr = (char *) 0;
  156.     myPB.ioVRefNum = 1;
  157.     myPB.ioCRefNum = refNum;
  158.     myPB.csCode = READTOC;
  159.     myPB.csParam[0] = 0;
  160.     myPB.csParam[1] = 1;
  161.     
  162.     result = PBControl(&myPB, false);
  163.     
  164.     if (result == noErr)
  165.         *numberTracks = (short) BCD2DECIMAL(myPB.csParam[1]);
  166.     return result;
  167. }
  168.  
  169. /************************************************************************
  170.  *
  171.  *  Function:        ReadTOC
  172.  *
  173.  *  Purpose:        read table of contents
  174.  *
  175.  *  Returns:        OSErr
  176.  *                    usually 0, but can be negative if driver returns
  177.  *                    an error
  178.  *
  179.  *  Side Effects:    fills trackInfo with absolute minute, second, block
  180.  *                    for each track.
  181.  *
  182.  *  Description:    We depend upon the trackInfo array already being
  183.  *                    allocated by the calling routine.
  184.  *                    Allocate the buffer to pass to
  185.  *                    the READTOC call.  Call the driver.  Loop through
  186.  *                    the READTOC buffer, converting values into the
  187.  *                    final buffer.
  188.  *
  189.  ************************************************************************/
  190. OSErr
  191. ReadTOC(refNum, numberTracks, trackInfo)
  192. short        refNum;
  193. short        numberTracks;
  194. TrackInfo    trackInfo[];
  195. {
  196.     CDPlay3Param    myPB;
  197.     OSErr    result;
  198.     char    *track;
  199.     short    trackSize;
  200.     short    i, j;
  201.     
  202.     trackSize = numberTracks * 4;        /* 4 bytes per track in call */
  203.     track = NewPtr(trackSize);
  204.     myPB.ioCompletion = 0;
  205.     myPB.ioNamePtr = (char *) 0;
  206.     myPB.ioVRefNum = 1;
  207.     myPB.ioCRefNum = refNum;
  208.     myPB.csCode = READTOC;
  209.     myPB.readType = BUFADDR;
  210.     myPB.bufAddr = track;
  211.     myPB.bufferLength = trackSize;
  212.     myPB.track = 1;
  213.     
  214.     result = PBControl(&myPB, false);
  215.     for (i = 0; i < numberTracks; i++)
  216.     {
  217.         j = i * 4;
  218.         trackInfo[i].minute = (long) BCD2DECIMAL(track[j+1]);
  219.         trackInfo[i].second = (long) BCD2DECIMAL(track[j+2]);
  220.         trackInfo[i].block = (long) BCD2DECIMAL(track[j+3]);
  221.     }
  222.     DisposPtr(track);
  223.     return result;
  224. }
  225.  
  226.  
  227. /************************************************************************
  228.  *
  229.  *  Function:        CFormatString
  230.  *
  231.  *  Purpose:        prepare return string
  232.  *
  233.  *  Returns:        nothing
  234.  *
  235.  *  Side Effects:    creates C string from input parameters
  236.  *
  237.  *  Description:    For each of the numArgs values in num[], convert the 
  238.  *                    value to an ascii string and concatenate.
  239.  *
  240.  ************************************************************************/
  241. void
  242. CFormatString(str, num, numArgs)
  243. char    str[];
  244. long     num[];
  245. long    numArgs;
  246. {
  247.     short    i;
  248.     char    numStr[31];
  249.     
  250.     ltoa(num[0], str);
  251.     for (i = 1; i < numArgs; i++)
  252.     {
  253.         strcat(str, ",");        /* add comma to separate items */
  254.         ltoa(num[i], numStr);
  255.         strcat(str, numStr);
  256.     }
  257. }
  258.  
  259.  
  260. /* C routines for HyperCard callbacks */
  261. #include <XCmdGlue.inc.c>
  262.